package com.hitechbangla.fctu.base.radar;

import com.hitechbangla.fctu.base.Location;
import com.hitechbangla.fctu.base.aircraft.Aircraft;
import com.hitechbangla.fctu.utility.GeneralUtil;
import fctu.simulator.HTB_MAIN;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.List;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Point2D;
import java.io.Serializable;
import java.text.DecimalFormat;
import java.util.ArrayList;


/**
 *
 * @author deb kanti
 */

public class AutoLock implements Serializable
{
    private transient HTB_MAIN htb_main;
    private int phase; // phase 0 means no aircraft autolocked yet, 1 means 1 autolocked, and so on
    private final int range = 5;
    private Aircraft aircraftFirst;
    private Aircraft aircraftSecond;    
    
    private final int RECT_SIZE = 10;
    private Radar radar;
    private List<AutoLockPair> listAutoLockPair;    
    
    public AutoLock(Radar radar)
    {	
	phase = 0;
	this.radar = radar;
	this.radar.addAutoLock(this);
	listAutoLockPair = new ArrayList<>();
    }

    public void executeRemoveAutoLock(Point2D point)
    {
	checkIfAutoLockLineClicked(point);
    }
    
    private void checkIfAutoLockLineClicked(Point2D point)
    {
	Point2D point2 = new Point2D.Double();
	point2.setLocation(point.getX()*HTB_MAIN.one_nm_equivalent_pixel, point.getY()*HTB_MAIN.one_nm_equivalent_pixel);
	
	for(AutoLockPair autoLockPair:listAutoLockPair) 
	{
	    Detected detectedFirst = getDetected(autoLockPair.getAircraftFirst());
	    Detected detectedSecond = getDetected(autoLockPair.getAircraftSecond());
	    
	    //System.out.println("from autolock x: " + point2.getX());
	    //System.out.println("from autolock y: " + point2.getY());
	    //System.out.println("from detected first x: " + detectedFirst.getAcPosX());
	    //System.out.println("from detected first y: " + detectedFirst.getAcPosY());
	    //System.out.println("from detected second x: " + detectedSecond.getAcPosX());
	    //System.out.println("from detected second y: " + detectedSecond.getAcPosY());
	    
	    
	    if(GeneralUtil.isPointCloseToLine((float)point2.getX(), (float) point2.getY(), (float)detectedFirst.getAcPosX(), (float)detectedFirst.getAcPosY(), (float)detectedSecond.getAcPosX(), (float)detectedSecond.getAcPosY()))
	    {
		listAutoLockPair.remove(autoLockPair);
	    }
	}
    }
    
    private Detected getDetected(Aircraft aircraft)
    {
	for(Object objectDetected : this.radar.getDetectedMap().values())
	{
	    Detected detected = (Detected)objectDetected;
	    
	    if(detected.getAircraft().getAircraftState().getCallSign().equals(aircraft.getAircraftState().getCallSign()))
	    {
		return detected;
	    }
	}
	return null;
    }
    
    public void execute(Point2D point)
    {
	checkIfAircraftClicked(point);	
	////System.out.println("From Autolock x:" + point.getX() + ", y:" + point.getY());
    }
    
    
    
    
    private void checkIfAircraftClicked(Point2D point)
    {
	//List<Aircraft> listAirCraft = HTB_MAIN.gameScene.airCraftList;
	
	for(Object object : this.radar.getDetectedMap().values())
	{
	   Detected detected = (Detected)object;
	   Aircraft aircraft = detected.getAircraft();
	   
	   ////System.out.println("from autolock: aircraft detected");
	   
	   if(withinRange(aircraft,point))
	    {		
		if(getPhase() == 0) // no aircraft locked yet or complete autolocking pair created
		{
		    aircraftFirst = aircraft;
		    phase = 1; // one aircraft selected
		    
		    // now adding first aircraft to airadar
		    aircraftFirst.addAIRadar(this.radar.getAiRadar());
		    
		    if(!(aircraftFirst == this.radar.getAiRadar().getOwnerAircraft()))
		    {
			this.radar.getAiRadar().getAircraftCheckList().clear();
		    }		    
		    //		    
		}		
		else if(getPhase() == 1)
		{
		    aircraftSecond = aircraft;
		    
		    AutoLockPair autoLockPair = new AutoLockPair(aircraftFirst, aircraftSecond);
		    getListAutoLockPair().add(autoLockPair);		    
		    
		    // now adding this aircraft to airradar checklist, to check whether this aircraft is within airadar range or not
		    this.radar.getAiRadar().getAircraftCheckList().add(aircraftSecond);
		    
		    // initialize local aircrafts to null
		    aircraftFirst = null;
		    aircraftSecond = null;
		    
		    phase = 0; // second aircraft selected
		    //
		}
		return;
	    }
	}	
    }

    private boolean withinRange(Aircraft aircraft, Point2D point)
    {	
	Point2D point2 = new Point();
	point2.setLocation(point.getX()*HTB_MAIN.one_nm_equivalent_pixel, point.getY()*HTB_MAIN.one_nm_equivalent_pixel);
	double distX = Math.abs((double)point2.getX() - aircraft.getAircraftState().getLocation().getX());
	double distY = Math.abs((double)(point2.getY() - aircraft.getAircraftState().getLocation().getY()));
	return (distX<range && distY <range);	
    }

    /**
     * @return the phase
     */
    public int getPhase() {
	return phase;
    }

    /**
     * @return the aircraftFirst
     */
    public Aircraft getAircraftFirst() {
	return aircraftFirst;
    }

    /**
     * @return the aircraftSecond
     */
    public Aircraft getAircraftSecond() {
	return aircraftSecond;
    }

    /**
     * @return the listAutoLockPair
     */
    public List<AutoLockPair> getListAutoLockPair() {
	return listAutoLockPair;
    }

    public void draw(Graphics g)
    {
	Graphics2D g2d = (Graphics2D)g;
	
	Detected detectedFirst = null, detectedSecond = null;
	    
	for (AutoLockPair autoLockPair : getListAutoLockPair()) 
	{
	    Aircraft aircraftFirst = autoLockPair.getAircraftFirst();
	    Aircraft aircraftSecond = autoLockPair.getAircraftSecond();

	    if (this.radar.isOutOfRange(aircraftFirst) || this.radar.isOutOfRange(aircraftSecond)) {
		this.getListAutoLockPair().remove(autoLockPair);
	    }

	    // drawing the first aircraft
	    for (Object objectDetected : this.radar.getDetectedMap().values()) 
	    {
		Detected detected = (Detected) objectDetected;

		if (detected.getAircraft().getAircraftState().getCallSign().equals(aircraftFirst.getAircraftState().getCallSign())) 
		{
		    g.setColor(Color.RED);
		    g2d.drawRect((int) (detected.getAcPosX() * HTB_MAIN.one_px_equivalent_naut) - 5, (int) (detected.getAcPosY() * HTB_MAIN.one_px_equivalent_naut) - 4, 10, 10);
		    detectedFirst = detected;
		    break;
		}
	    }

	    // drawing the second aircraft
	    for (Object objectDetected : this.radar.getDetectedMap().values()) 
	    {
		Detected detected = (Detected) objectDetected;

		if (detected.getAircraft().getAircraftState().getCallSign().equals(aircraftSecond.getAircraftState().getCallSign())) {
		    g.setColor(Color.RED);
		    g2d.drawRect((int) (detected.getAcPosX() * HTB_MAIN.one_px_equivalent_naut) - 5, (int) (detected.getAcPosY() * HTB_MAIN.one_px_equivalent_naut) - 4, 10, 10);
		    detectedSecond = detected;
		    break;
		}
	    }

	    // drawing the line and text between them
	    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
	    g2d.drawLine((int) (detectedFirst.getAcPosX() * HTB_MAIN.one_px_equivalent_naut), (int) (detectedFirst.getAcPosY() * HTB_MAIN.one_px_equivalent_naut), (int) (detectedSecond.getAcPosX() * HTB_MAIN.one_px_equivalent_naut), (int) (detectedSecond.getAcPosY() * HTB_MAIN.one_px_equivalent_naut));

	    float distance = (float) GeneralUtil.distance2D(detectedFirst.getAcPosX(), detectedFirst.getAcPosY(), detectedSecond.getAcPosX(), detectedSecond.getAcPosY());
	    int stringPositionX = (int) ((detectedFirst.getAcPosX() + detectedSecond.getAcPosX()) * HTB_MAIN.one_px_equivalent_naut / 2) - 10;
	    int stringPositionY = (int) ((detectedFirst.getAcPosY() + detectedSecond.getAcPosY()) * HTB_MAIN.one_px_equivalent_naut / 2) + 5;

	    // drawString(,);
	    HTB_MAIN.customDrawString(g, "distance:" + String.valueOf((int) distance), new Point(stringPositionX, stringPositionY));

	    double heading = GeneralUtil.getHeadingWithOther(detectedFirst.getAcPosX(), detectedFirst.getAcPosY(), detectedSecond.getAcPosX(), detectedSecond.getAcPosY());
	    HTB_MAIN.customDrawString(g, "heading:" + String.valueOf((int) heading), new Point(stringPositionX, stringPositionY + 12));
            
             //added by bks
            /*
            float drss = detectedSecond.getAircraft().getAircraftState().getSpeed();
            float drsf = detectedFirst.getAircraft().getAircraftState().getSpeed();
            float rslt = drss/drsf;
            //System.out.println("drsf speed: "+drsf);
            //System.out.println("drss speed: "+drss);
            //System.out.println("r speed: "+rslt);
            */
            
            double relativeSpeed = (detectedSecond.getAircraft().getAircraftState().getSpeed())/(detectedFirst.getAircraft().getAircraftState().getSpeed());
            DecimalFormat df = new DecimalFormat();
            df.setMaximumFractionDigits(2);
            ////System.out.println(df.format(relativeSpeed));
            String sSpeed = df.format(relativeSpeed);

            HTB_MAIN.customDrawString(g, "Relative Speed:" + sSpeed /*String.valueOf((float) relativeSpeed)*/, new Point(stringPositionX, stringPositionY + 24));
            ////System.out.println("Relative speed: "+relativeSpeed);


	}

	if (this.getPhase() == 1) 
	{
	    for (Object objectDetected : this.radar.getDetectedMap().values()) 
	    {
		Detected detected = (Detected) objectDetected;

		if (detected.getAircraft().getAircraftState().getCallSign().equals(this.getAircraftFirst().getAircraftState().getCallSign())) {
		    g.setColor(Color.RED);
		    g2d.drawRect((int) (detected.getAcPosX() * HTB_MAIN.one_px_equivalent_naut) - 5, (int) (detected.getAcPosY() * HTB_MAIN.one_px_equivalent_naut) - 4, 10, 10);
		}
	    }
	}
    }

    /**
     * @return the locationFirstAircraft
     */
    /*
    public Location getLocationFirstAircraft() {
	return locationFirstAircraft;
    }

*/ 
    /**
     * @param locationFirstAircraft the locationFirstAircraft to set
     */
    
    /*
    public void setLocationFirstAircraft(Location locationFirstAircraft) {
	this.locationFirstAircraft = locationFirstAircraft;
    }
    */

    /**
     * @return the locationSecondAircraft
     */
    
    /*
    public Location getLocationSecondAircraft() {
	return locationSecondAircraft;
    }
    */
    /**
     * @param locationSecondAircraft the locationSecondAircraft to set
     */
    /*
    public void setLocationSecondAircraft(Location locationSecondAircraft) {
	this.locationSecondAircraft = locationSecondAircraft;
    }
    */
}


